package epoch.game.core.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import java.nio.charset.Charset;
import java.util.Objects;

import epoch.game.core.buffer.IBuffer;

public class NettyBuffer implements IBuffer {
	
	private ByteBuf buffer;

	public NettyBuffer() {
		this(0);
	}

	public NettyBuffer(int initialSizeHint) {
		buffer = Unpooled.unreleasableBuffer(Unpooled.buffer(initialSizeHint, Integer.MAX_VALUE));
	}

	public NettyBuffer(byte[] bytes) {
		buffer = Unpooled.unreleasableBuffer(Unpooled.buffer(bytes.length, Integer.MAX_VALUE)).writeBytes(bytes);
	}

	public NettyBuffer(String str, String enc) {
		this(str.getBytes(Charset.forName(Objects.requireNonNull(enc))));
	}

	public NettyBuffer(ByteBuf buffer) {
		this.buffer = Unpooled.unreleasableBuffer(buffer);
	}

	@Override
	public byte readByte() {
		return buffer.readByte();
	}

	@Override
	public short readShort() {
		return buffer.readShort();
	}

	@Override
	public char readChar() {
		return buffer.readChar();
	}

	@Override
	public int readInt() {
		return buffer.readInt();
	}

	@Override
	public long readLong() {
		return buffer.readLong();
	}

	@Override
	public float readFloat() {
		return buffer.readFloat();
	}

	@Override
	public double readDouble() {
		return buffer.readDouble();
	}
	
	@Override
	public void readBytes(byte[] bytes) {
		buffer.readBytes(bytes);
	}

	@Override
	public byte[] array() {
		return buffer.array();
	}
	
	@Override
	public byte[] readableArray() {
		byte[] bytes = new byte[buffer.readableBytes()];
		buffer.readBytes(bytes);
		return bytes;
	}

	@Override
	public IBuffer writeByte(byte b) {
		buffer.writeByte(b);
		return this;
	}

	@Override
	public IBuffer writeShort(short s) {
		buffer.writeShort(s);
		return this;
	}

	@Override
	public IBuffer writeChar(char c) {
		buffer.writeChar(c);
		return this;
	}

	@Override
	public IBuffer writeInt(int i) {
		buffer.writeInt(i);
		return this;
	}

	@Override
	public IBuffer writeLong(long l) {
		buffer.writeLong(l);
		return this;
	}

	@Override
	public IBuffer writeFloat(float f) {
		buffer.writeFloat(f);
		return this;
	}

	@Override
	public IBuffer writeDouble(double d) {
		buffer.writeDouble(d);
		return this;
	}

	@Override
	public IBuffer writeBytes(byte[] bytes) {
		buffer.writeBytes(bytes);
		return this;
	}
	
	@Override
	public IBuffer writeBytes(byte[] bytes, int offset, int len) {
		buffer.writeBytes(bytes,offset,len);
		return this;
	}


	@Override
	public void flip() {
		//do nothing
	}

	@Override
	public void setAutoExpand(boolean autoExpand) {
		//do nothing
	}

	@Override
	public int readableBytes() {
		return buffer.readableBytes();
	}

	@Override
	public int writableBytes() {
		return buffer.writableBytes();
	}

	@Override
	public int readIndex() {
		return buffer.readerIndex();
	}

	@Override
	public int writeIndex() {
		return buffer.writerIndex();
	}
}
